静的サイトジェネレーター Gatsby
静的サイトジェネレーターとは?
Static Site Generator(SSG)
WebサイトのHTMLファイルを生成するツールのこと
Wordpressのような従来CMSの仕組みは、MySQLなどのDBをもとに、サーバーでHTMLを生成して返すものだった
https://user-images.githubusercontent.com/7469495/77660631-ec775600-6fbc-11ea-954f-46f16c1c1fcf.png
それに対し静的サイトジェネレーターは、コンパイル時にGraphQLやAPIからすべてのデータを取得し全てのHTMLを最初に生成する
さらに、生成されたファイルを、Netlifyなどのホスティングサービスを用いて、サーバーレスで公開する仕組みが主流になっている
https://gyazo.com/f5e2444c352c93ab967b94bf3c8f1f49
静的サイトジェネレーターのメリット
レスポンスが速い。サーバーでHTMLを動的に生成しないから
サーバー代 ¥0✨ サーバーが必要ないため
サーバー落ちない。メンテが不要
※ ただしNetlifyなどのホスティングサービスが落ちる可能性はあります
headless CMS と相性が良い
headless CMS・・・HTMLなどビュー機能がないCMS。コンテンツを管理する仕組みのみを持ち、APIのみ提供する
onuma.icon HTMLを生成しない?
nishiyamayudai.iconJSONでコンテンツをPOSTし、GETでコンテンツがJSONで配信されます。Contentfulだと管理画面もあります
LPやブログなどに相性が良い
デメリット
膨大なページ量のWebサイトには向かない
ビルドの時間がかかる。ページ数が多くなるほど遅くなる
頻繁にデータ更新があるサイトに向かない
データの更新のたびにビルドを走らせる必要があるため
API頻繁にリクエストするサイトには向かない
有名な静的サイトジェネレーター
400を超える数がある
https://gyazo.com/6a2e9887da01bb389626589d54cb65fe
過去2年で、フレームワークが成熟したらしく、代表的なものは以下↓
Gatsby
これが一番有名、欧米で流行っている。
React.js、Webpack、GraphQL、CSSなどで SPA を作成するのに最適
Headless CMS、SaaSサービス、API、データベースなどに対応
Next, Nuxt
Gatsbyが登場する前は、Next, Nuxt が主流だった
Gridsome も人気になりました。
Hugo
Jekyll
https://gyazo.com/0c9205e71eb0e17513f4f62067b2ad1f
Gatsbyの特徴
https://gyazo.com/6d5382dfae42e30934c305f6d8b4b8cd
Reactベース
GraphQLと相性良い
Gatsby, Inc.(2015年設立)が開発、シリコンバレーにある
IBM、PayPal、Braun、Airbnb などが利用
静的サイトジェネレータは、もともとNextやNuxtのアイデンティティでしたが
Gatsbyの登場により静的サイトジェネレータは別にNextやNuxtじゃなくてもいいのでは?という風潮になってきた
Gatsbyプラグインが多数、npmで公開されていて以下のようなことができる
TypeScript化, PWA対応, WordPress連携, Contentful連携,GA組み込み などなど
Jamstack(ジャムスタック)と Lampstack(ランプスタック)
Gatsbyに代表されるようなモダンなウェブサイトの仕組みのことを指すワードがここ1〜2年で注目されてきた
対義語としてLampstackがある
Jamstack
J ・・・ JavaScript
a ・・・ API
m ・・・ Markup
Webサーバーに依存しない、つまりサーバーレスであるウェブサイトのことをJamstackであると言える
Lampstack
L ・・・ Linux
a ・・・ Apache, Webサーバ
m ・・・ MariaDB・MySQL
p ・・・ PHP・Perl・Python
WordPress のようなサーバーサイドとクライアントサイドが密結合なウェブサイトをLampstackであると言える
Create React App, Nuxt (Next), Gatsby の使い分け
Create React App
すべてCSR(クライアントサイドレンダリング)SEOを捨てることになる
ブラウザベースのWEBアプリケーションに向いている
管理画面。
APIのレスポンスを待ってDOM描画するため、描画まで待ち時間が発生する
コーポレートサイトやLPには不向き
tj.icon 100% control
Nuxt (Next)
APIのレスポンス結果も含めてSSRするのでSEOは完璧。
データ更新が多い(APIレスポンスが頻繁に変わる)サイトに向いている
universalモードの時
tj.icon best practice
Gatsby
ビルド時点で静的なHTMLを生成する。SEOは完璧。描画や遷移が爆速。
ただし、頻繁なデータ更新には向かない。都度ビルドとデプロイが必要。
tj.icon serverless + JAMStack
table:table
Create React App Nuxt Gatsby
SEO × ◯ ◯
頻繁なデータ更新 △ ◎ △
描画速度 △ ◯ ◯
LP × ◯ ◯
CMS系(e.g. ブログ, コーポレートサイト) △ ◯ ◎
WEBアプリ(e.g. TODOアプリ) ◯ ◯ ×
大規模Webサービス × ◎ ×
Gatsbyを試したサンプル
自分の環境で試したい方は
公式ドキュメントのクイックスタートで簡単に試すことができます
gatsby-cli をインストールし、開発環境を作るとあらかじめディレクトリ、ファイルなどが用意されます
以下コマンドで開発環境を起動します
code: (sh)
$ gatsby develop
少し触ってみたサンプル
遷移には <Link></Link> を使う
pjaxのような挙動をする
カーソルをリンク先に乗せた瞬間に、遷移先のhtmlをprefetchし、DOM書き換えとpushStateにより遷移
これにより爆速で遷移される
GraphQLを試す
起動後
http://localhost:8000/___graphql にアクセスすると、GraphQL Explorerが使える
GraphQL を用いて.md からデータを取得する
code: (sh)
$ yarn add gatsby-source-filesystem gatsby-transformer-remark
gatsby-config.js に以下を追記
code: (javascript)
// gatsby-config.js
// ローカルファイルのデータをGatsbyに渡せるプラグイン
{
resolve: "gatsby-source-filesystem",
options: {
path: ${__dirname}/blog,
name: "blog",
},
},
/blog 以下のファイルをgraphQLで取得できるようになる
/blog/hello-world.md を追加
code: (markdown)
---
title: Hello World this is title.
date: "2020-04-01"
categories: []
---
これは、hello-world.md の本文です。
**太字**
## 見出し
Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。
Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。
さらに、/pages/get-markdown.js を追加
code: (javascript)
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Layout from "../components/Layout"
const GetMarkdown = () => {
// useStaticQuery は gatsby に用意されているメソッド
// ビルド時にGraphQLでクエリすることができる
const data = useStaticQuery(graphql`
query {
totalCount
edges {
node {
id
html # 本文をHTMLに変換して取得する
frontmatter {
title
date(formatString: "YYYY年MM月DD日")
}
excerpt # 本文抜粋
}
}
}
}
`);
console.log('data:', data);
return (
<Layout>
<strong>投稿数 ( {data.allMarkdownRemark.totalCount} ) </strong>
{data.allMarkdownRemark.edges.map(
({
node: {
id,
html,
frontmatter: { title, date },
excerpt,
},
}) => (
<div key={id}>
<div>{date}</div>
<h2>{title}</h2>
{/* <p>本文抜粋:{excerpt}</p> */}
<div dangerouslySetInnerHTML={{ __html: html }} />
</div>
)
)}
</Layout>
)
}
export default GetMarkdown;
Contentful からデータを取得し、DOMに反映する
code: (sh)
$ yarn add gatsby-source-contentful
gatsby-config.js に以下を追記
code: (javascript)
// contenful からデータを取ってくるプラグイン
{
resolve: gatsby-source-contentful,
options: {
spaceId: '**********',
accessToken: '**********',
},
},
spaceId accessToken はContentfulの管理画面から取得できる
今回はシンプルに以下のようなUserデータを作成
table:table
name age
john 5
umamichi 27
pages/contentful.js を作成
code: (javascript)
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Layout from "../components/Layout"
const Contentful = () => {
const data = useStaticQuery(graphql`
query {
# contentful からデータを取得する
allContentfulUser {
edges {
node {
id
age
name
}
}
}
}
`);
console.log('data:', data);
return (
<Layout>
{data.allContentfulUser.edges.map((
{
node: { id, name, age }
}
) => (
<h3 key={id}>
{name} (age: {age})
</h3>
))}
</Layout>
)
}
export default Contentful;
試したい方は、詳細な手順はこちらから。
ビルドしてNetlifyで公開する
ビルド
code: (sh)
$ gatsby build
public ディレクトリにこのようにファイルが生成される
https://gyazo.com/c9e09310797e3232110d102644a5cc51
contentfulのデータなども一式組み込まれている
ちなみに、上記のサンプル含めたった4ページでビルドにかかった時間は 27.9s
こちらはまだまだ改善の余地ありそう。というかぜひしていただきたい。
Netlifyの公開手順は省略しますが、このあたりの記事を参考にしてみてください。5分で公開完了 GitHub PagesはCDNが弱いらしい
サブディレクトリが必要。。。
React -> Zeit now
Command Line
Vue -> Netlify
UI
Amplify 今年人気
Firebase
まとめ
Gatsbyに代表される静的サイトジェネレーターによりwebpackで環境構築するコストが削減できる
ページ遷移の爆速化、画像の最適化圧縮なども自動で行ってくれる
WordPressなどSSRのCMSが淘汰される
Gatsbyの学習コストは肌感でjQuery習得くらい。ただ、山のようにあるプラグインを使いこなせるかが重要
保守されなくなるプラグインありそうなので、プラグイン選びは慎重にすべき
頻繁にAPIリクエストするような動的Webサイト以外はすべて、Gatsby採用しても良いでしょう
HTMLコーダーに求められるスキルがReact込みになってくる
onuma.icon コーダーはReactよりVue.jsの方がいいような気はしますが、その辺どうなんですかね?🤔
日本は世界のトレンドから1年くらい遅れる傾向があるので2020年から静的サイトジェネレータがもっと普及していくと予想(期待)
nishiyamayudai.icon同感
Svelte + Vue(reactive data)
React (immutable data)
XState
code:reactive data
let a = 1
a++
// a = 2
code:immutable data
const a = 1
const _a = a + 1
// _a
参考